package dao;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import util.Conversion;
import dto.CategoryDTO;
import dto.DomainDTO;
import entities.Category;
import entities.Domain;

/**
 * Session Bean implementation class CategoryDAO
 */
@Stateless
public class CategoryDAO implements CategoryDAORemote {
	@PersistenceContext
	EntityManager em;

	public CategoryDAO() {
	}

	@Override
	public void addCategory(CategoryDTO cDto) throws Exception {
		try {

		} catch (Exception e) {
			throw new Exception("Category could not been added!", e);
		}
	}

	@Override
	public void addCategory(CategoryDTO cDTO, DomainDTO dDTO) throws Exception {
		try {
			cDTO.setDomain(dDTO);
			Conversion conv = new Conversion();
			Category c = conv.fromCategoryDTOToCategory(cDTO);
			c.setDomain(em.find(Domain.class, dDTO.getId()));
			em.persist(c);

			Category cc = em
					.find(Category.class, getCategoryId(cDTO.getName()));

			Domain d = em.find(Domain.class, dDTO.getId());

			d.getCategories().add(cc);

		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error adding new category!", e);
		}
	}

	@Override
	public CategoryDTO getCategoryByNameDomain(String categName, int domainID)
			throws Exception {
		Conversion conv = new Conversion();
		TypedQuery<Category> query = em.createQuery(
				"SELECT c FROM Category c WHERE c.name = :nameCateg ",
				Category.class);
		query.setParameter("nameCateg", categName);
		List<Category> result = query.getResultList();
		if (result.size() > 0) {
			for (Category c : result)
				if (c.getDomain().getId() == domainID)
					return conv.fromCategoryToCategoryDTO(c);
		}
		return null;
	}

	@Override
	public void removeCategory(CategoryDTO cDTO) throws Exception {
		try {
			Category c = em.find(Category.class, cDTO.getId());
			c.getDomain().getCategories().remove(c);
			em.remove(c);

		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error adding new domain!", e);
		}
	}

	public List<CategoryDTO> getCategoryByDomain(int domainID) {
		Conversion conv = new Conversion();
		TypedQuery<Category> query = em
				.createQuery(
						"SELECT c FROM Domain d JOIN d.categories c WHERE d.id = :idDomain ",
						Category.class);
		query.setParameter("idDomain", domainID);
		List<Category> result = query.getResultList();
		List<CategoryDTO> dtoList = new ArrayList<CategoryDTO>();
		for (Category c : result) {

			try {
				dtoList.add(conv.fromCategoryToCategoryDTO(c));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return dtoList;
	}

	@Override
	public CategoryDTO getCategoryByName(String domainName) throws Exception {
		Conversion conv = new Conversion();
		TypedQuery<Category> query = em.createQuery(
				"SELECT c FROM Category c WHERE c.name = :idDomain ",
				Category.class);
		query.setParameter("idDomain", domainName);
		List<Category> result = query.getResultList();
		if (result.size() > 0)
			return conv.fromCategoryToCategoryDTO(result.get(0));
		return null;
	}

	@Override
	public CategoryDTO getCategoryByNameAndDomain(String domainName,
			int domainID) throws Exception {

		Conversion conv = new Conversion();
		TypedQuery<Category> query = em.createQuery(
				"SELECT c FROM Category c WHERE c.name = :nameCateg",
				Category.class);
		query.setParameter("nameCateg", domainName);
		List<Category> result = query.getResultList();
		if (result.size() > 0)
			for (Category c : result) {
				if (c.getDomain().getId() == domainID)
					return conv.fromCategoryToCategoryDTO(c);
			}
		return null;
	}

	// Tamas -> fishy
	@Override
	public CategoryDTO getCategoryById(int catID) {
		Conversion conv = new Conversion();
		TypedQuery<Category> query = em
				.createQuery("SELECT c FROM Category c WHERE c.id = :idCat ",
						Category.class);
		query.setParameter("idCat", catID);
		List<Category> result = query.getResultList();
		CategoryDTO catDTO = new CategoryDTO();
		try {
			if (result.size() > 0) {
				catDTO = conv.fromCategoryToCategoryDTO(result.get(0));
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return catDTO;
	}

	@Override
	public int getCategoryId(String cName) {
		TypedQuery<Category> query = em.createQuery(
				"SELECT c FROM Category c WHERE c.name = :nameCateg",
				Category.class);
		query.setParameter("nameCateg", cName);
		List<Category> result = query.getResultList();
		if (result.size() > 0)
			return result.get(0).getId();
		return -1;
	}

}
